import {get, post, del} from '../api/ajax'
import WPopView from '@/utils/popView'
import { ListType, PageDataType } from './types'
import {dateAndTime} from "@/utils/date";

// 必须继承才能使用
class BaseModel {

  public _id = ''
  // 创建时间
  public createTime = ''

  static loadListApi = ''
  // 删除数据的API
  removeDataApi = ''
  // 添加数据的API
  addModelApi = ''
  // 添加项目的字段
  addModelField = ''
  // 加载所有数据
  static loadAllApi = ''
  // 获取详情API
  detailApi = ''

  get createTimeStr() {
    return dateAndTime(this.createTime)
  }

  static create<T extends BaseModel>(data = {}): T {
    const model = new this()
    model.setDataWithJson(data)
    return model as unknown as T
  }


  // 根据数据设置对象并获取
  public static creatModelWithJson<T extends BaseModel>(json: object): T {
    const model = new this()
    model.setDataWithJson(json)
    return model as T
  }

  // 根据json数组获取数组对象
  public static getModelsWithArr<T extends BaseModel>(dataArr: T[]): Array<T> {
    if (dataArr instanceof Array) {
      return dataArr.map((item) => {
        return this.creatModelWithJson(item)
      })
    } else {
      return []
    }
  }

  // 设置数据
  public setDataWithJson(data: {} | string) {
    if (!data) return
    if (typeof data === 'string') {
      this._id = data
    } else {
      for (const key in data) {
        if ((this as any)[key] !== undefined) {
          (this as any)[key] = (data as any)[key]
        }
      }
    }
  }

  // 根据传入的数组获取模型
  public getJson(keys: string[] | string, json = {}) {
    const newKeys = typeof keys === 'string' ? keys.split(' ') : [...keys]
    if (newKeys instanceof Array) {
      newKeys.forEach((key) => {
        (json as any)[key] = (this as any)[key]
      })
    }
    return json
  }

  // 获取json对象
  public static getJson(obj: BaseModel, keys: string[], json = {}) {
    return obj.getJson(keys, json)
  }

  public static loadModels<T extends BaseModel>(pageData: PageDataType, otherData = {}): Promise<ListType<T>> {
    return new Promise((resolve, reject) => {
      get<ListType<T>>(this.loadListApi, {
        ...pageData,
        ...otherData
      }).then((data: ListType<T>) => {
        resolve({
          total: data.total,
          list: this.getModelsWithArr<T>(data.list)
        })
      }).catch((err) => {
        reject(err)
      })
    })
  }

  // 加载所有数据
  public static loadAllModels<T extends BaseModel>(): Promise<Array<T>> {
    return new Promise<Array<T>>((resolve, reject) => {
      get<Array<T>>(this.loadAllApi).then((dataArr: Array<T>) => {
        resolve(this.getModelsWithArr(dataArr))
      }).catch((err) => {
        reject(err)
      })
    })
  }

  /**
   * 删除数据
   */
  removeData(msg: string, other = {}) {
    return new Promise((resolve, reject) => {
      WPopView.confirm('删除提示', msg).then(() => {
        del(`${this.removeDataApi}/${this._id}`, other).then(() => {
          resolve()
        }).catch(() => {
          reject()
        })
      }).catch(() => {
        reject()
      })
    })
  }

  /**
   * 获取详情
   */
  getDeatil<T extends BaseModel>(): Promise<T> {
    return new Promise((resolve, reject) => {
      get<T>(`${this.detailApi}/${this._id}`).then((data: T) => {
        this.setDataWithJson(data)
        resolve(this as unknown as T)
      }).catch(() => {
        reject()
      })
    })
  }

  /**
   * 创建项目
   */
  addModel(keys?: string, other = {}) {
    return post(this.addModelApi, this.getJson(keys || this.addModelField, other))
  }

}

export default BaseModel
